<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
  <title>CrossSlide</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="google-site-verification" content="51fRdx-2ED6h7sM165D6xFt80WIlp0c4vc24M8vUcQ8">
  <link rel='stylesheet' href='Stylesheet/style.css'>
</head>
<body>
<div class=body>

<h1>CrossSlide</h1>
<em>A jQuery plugin to create pan and cross-fade animations</em>

<p class=menu>
<a href='http://github.com/tobia/CrossSlide'>Project page</a> –
<a href='http://github.com/tobia/CrossSlide/raw/master/jquery.cross-slide.min.js'><b>Download minified</b></a> –
<a href='http://github.com/tobia/CrossSlide/raw/master/jquery.cross-slide.js'>Download source</a> –
<a href='email.html'>Bugs, feature requests and support</a>
</p>
<hr>

<p>CrossSlide is a <a href='http://jquery.com/'>jQuery</a> plugin implementing
in 2kB<sup><a name=use1 href=#note1>1</a></sup> of Javascript code some common
slide-show animations, traditionally only available via Adobe Flash™ or other
proprietary plugins. CrossSlide builds upon jQuery's animation facility, so it
is as portable across browsers as jQuery itself (that is, a lot!)</p>

<p>Internally CrossSlide does not rely on lookup tables, building instead a
"chain" of functions. Each function starts a linear phase of the animation
through jQuery, setting the next function in the chain as a complete callback.
After all the functions are prepared and the animation is started, no other
calculations are made. This setup reduces runtime overhead to the absolute
minimum, making CrossSlide the most optimized implementation of these
effects.</p>

<p>CrossSlide can create a few different effects, depending on how it's
called.</p>

<h2>Static cross-fade</h2>

<div class=demo id=test1>Loading...</div>

<p>The simplest effect, a cross-fade between static pictures is just as simple
to set up:</p>

<pre><code>$('#placeholder').crossSlide({
  sleep: 2,
  fade: 1
}, [
  { src: 'sand-castle.jpeg' },
  { src: 'sunflower.jpeg'   },
  { src: 'flip-flops.jpeg'  },
  { src: 'rubber-ring.jpeg' }
]);
</code></pre>

<p><code>#placeholder</code> is the block-level element (such as a
<code>div</code>) whose contents will be replaced with the animation. What you
put inside it in your HTML is only shown while the images are being preloaded,
or if the user-agent has JavaScript turned off. The current version of
CrossSlide waits until all the images are preloaded before starting the
slideshow, so I usually put the first image as a background-image of the div,
so that users with a slow connection won't see a big hole in the website while
all the images are being loaded.</p>

<p>The first parameter to the <code>crossSlide()</code> function call is a
dictionary of options. The second parameter is an array of objects, defining
the sequence of pictures, each with its source path and various attributes.</p>

<p>To get the static cross-fade effect you must specify the <code>sleep</code>
option, which is the time every image will take on its own, and the
<code>fade</code> option, which is the duration of each cross-fade animation
between images. Both are expressed in seconds and can accept decimal values.</p>

<h2>Slide and cross-fade</h2>

<p>This is the kind of animation from which the plugin takes its name. It shows
a sequence of pictures moving at a constant speed in alternating directions,
with a cross-fade effect between any two pictures.</p>

<div class=demo id=test2>Loading...</div>

<p>Here is the jQuery code to set it up:</p>

<pre><code>$('#placeholder').crossSlide({
  speed: 45,
  fade: 1
}, [
  { src: 'sand-castle.jpeg', dir: 'up'   },
  { src: 'sunflower.jpeg',   dir: 'down' },
  { src: 'flip-flops.jpeg',  dir: 'up'   },
  { src: 'rubber-ring.jpeg', dir: 'down' }
]);
</code></pre>

<p>Notice how the <code>speed</code> parameter, expressed in pixels/second, has
taken the place of <code>sleep</code>, as the images aren't static anymore, but
move with constant speed. <code>fade</code> is still required and still
expressed in seconds. You cannot use both <code>speed</code> and
<code>sleep</code> at the same time, because they trigger different
effects.</p>

<p>Additionally you have to specify the direction in which each image should be
moving. The plugin computes the rest, panning each image edge-to-egde at the
desired speed, in the desired direction. <code>dir</code> must be one of
<code>up</code>, <code>down</code>, <code>left</code> or <code>right</code>.
For best results I recommend using an even number of pictures and alternating
directions, as in the example.</p>

<h2>Ken Burns effect</h2>

<p>Finally, CrossSlide can be brought up to the full visual power of a
so-called Ken Burns effect: panning, zooming and fading each image to specific
points, to guide the eye of the viewer and convey meaning:</p>

<div class=right>
  <button id=freeze>Freeze</button><br>
  <button id=stop>Stop</button><br>
  <button id=restart>Restart</button><br><br>
  <button id=pause>Pause</button><br>
  <button id=resume>Resume</button>
</div>
<div class=demo id=test3>Loading...</div>
<div class=caption></div>

<p>In this case the jQuery code is a bit more complex, because it shows a
number of features:</p>

<pre><code>$('#placeholder').crossSlide({
  fade: 1
}, [
  {
    src:  'Images/sand-castle.jpeg',
    alt:  'Sand Castle',
    from: '100% 80% 1x',
    to:   '100% 0% 1.7x',
    time: 3
  }, {
    src:  'Images/sunflower.jpeg',
    alt:  'Sunflower',
    from: 'top left',
    to:   'bottom right 1.5x',
    time: 2
  }, {
    src:  'Images/flip-flops.jpeg',
    alt:  'Flip Flops',
    from: '100% 80% 1.5x',
    to:   '80% 0% 1.1x',
    time: 2
  }, {
    src:  'Images/rubber-ring.jpeg',
    alt:  'Rubber Ring',
    from: '100% 50%',
    to:   '30% 50% 1.5x',
    time: 2
  }
], function(idx, img, idxOut, imgOut) {
  if (idxOut == undefined)
  {
    // starting single image phase, put up caption
    $('div.caption').text(img.alt).animate({ opacity: .7 })
  }
  else
  {
    // starting cross-fade phase, take out caption
    $('div.caption').fadeOut()
  }
});
</code></pre>

<p>Every picture's pan &amp; zoom effect will last for <code>time</code>
seconds plus the two cross-fades, each taking an additional <code>fade</code>
seconds. <code>from</code> and <code>to</code> define the starting and ending
points of the effect, including the cross-fade part. They are expressed as a
background-position value, following the syntax of the CSS property of the same
name, plus an optional zoom factor. The zoom defaults to 1x if not provided.
The background-position part only accepts keywords and percent values, lengths
are not supported. As in CSS, the percentages are interpreted as horizontal
followed by vertical, while the keywords can be put in any order.</p>

<p>Every picture can be made a hyperlink, by adding a <code>href</code>
parameter with a relative or absolute URI to the option dictionary of the
single picture. You can also add an <code>onclick</code> parameter, pointing to
a function that will handle click events; <code>alt</code> to supply the
alternate text; and <code>target</code> to specify the target frame.</p>

<p>Other options you can put in the global dictionary are: <code>loop</code>
(numeric) to have the animation loop just once, or a fixed number of times, and
then stop; <code>shuffle</code> (boolean) to have CrossSlide automatically
shuffle the images before starting the slideshow; and <code>doubleFade</code>
(boolean) to have both a fade-out and a fade-in effect when switching images
(this is useful with transparent images.)</p>

<p>As shown in this example, CrossSlide accepts a callback function as a third
argument. This callback will be invoked at every keyframe, meaning when an image
starts to be cross-faded with another, and when the cross-fade ends and a single
image remains on screen. The callback will be passed either 2 or 4 arguments,
depending on the phase of the animation. If we are at the beginning of a single
image-phase, the callback will be passed 2 arguments: the index of the image in
the array and the <code>&lt;img&gt;</code> object currently being animated. If
we are at the beginning of a cross-fade, the callback will be passed 4
arguments: index and img element of the incoming image, plus index and img
element of the outgoing image. You can see how the example exploits this fact to
show a nice textual caption.</p>

<p>In case you're misunderstanding the above, I need to make clear that the
callback system is a programmer's tool and it can be used for much more than
captions. Still, if you can't write Javascript code, don't expect to be able to
make it work!</p>

<p>Finally, there are 5 methods you can invoke at runtime on the same object you
invoked <code>crossSlide()</code> on, to control the animation. The first 3 use
jQuery standard functions. The pause and resume methods, on the other hand,
require an extension to jQuery's animation facility, in the form of my own <a
href="/Pause/">jQuery Pause plugin</a>.
</p>
<ul>
<li><code>crossSlideFreeze()</code> will freeze the slideshow, using jQuery's
  <code>stop()</code> method, leaving the images in the position they where when
  you called it.</li>
<li><code>crossSlideStop()</code> will stop the slideshow and empty the
  container <code>div</code>; if the container was assigned a static background
  image or color by css, it will show through.</li>
<li><code>crossSlideRestart()</code> will stop the slideshow, if needed, and
  restart it from the beginning.</li>
<li><code>crossSlidePause()</code> will pause the slideshow.</li>
<li><code>crossSlideResume()</code> will resume a paused slideshow.</li>
</ul>

<h2>Ken Burns variant</h2>

<p>At the request of some users, here is a variant of the Ken Burns effect that
does away with the cross-fade between moving images, which is the phase most
demanding on the browser's rendering engine:</p>

<div class=demo id=test4>Loading...</div>

<p>This effect is turned on with the <code>variant</code> option. To get a
pleasing effect in this variant, a linear animation is not appropriate for the
single-image phase, so CrossSlide defaults to jQuery's built-in
<code>swing</code> mode. You can choose a different easing effect with the
<code>easing</code> option, which will be applied to single-image phases only:
cross-fade phases are still rendered with a linear animation. In this example
I'm using <code>easeInOutQuad</code> from George McGinley Smith's
<a href="http://gsgd.co.uk/sandbox/jquery/easing/">jQuery Easing Plugin</a>.</p>

<pre><code>$('#placeholder').crossSlide({
  fade: 1,
  variant: true,
  easing: 'easeInOutQuad'
}, [
  // as above
]);
</code></pre>

<h2>Performance</h2>

<p>jQuery animation effects rely on the browser for positioning, scaling and
cropping images, through CSS and the DOM. Thus it depends heavily on how the
browser and the underlying graphics platform optimize these operations.
Compared to native implementations of the same effects, CrossSlide is quite
CPU-intensive, but recent hardware handles a moderate usage without
problems.</p>

<p>Some browsers on some platforms apply a nice anti-alias filter to images when
you use a zoom factor in the Ken Burns mode, but most don't. Therefore I
recommend keeping your zoom factors below 1x, in order to avoid ugly 'pixel
mosaic' effects. You can tell that I didn't follow my own advice in this very
site by the ugly pixel noise in the Ken Burns examples above.</p>

<p>It also bears to mention that CSS and DOM force a script to round position
and size of images to integer pixel values, for every frame of an animation, not
just keyframes. This effectively makes it impossible to achieve slow, smooth
animations. If you are experiencing this issue, my only advice is to either make
the animation faster, do away with diagonal panning and/or image zooming, or
switch to a different animation technology.

<h2>How to use it</h2>

<p>Here is a simple guide on how to put CrossSlide on a website:</p>

<ol>
<li><p>Download the <a href="http://www.jquery.com/">jQuery</a> library and
include it along with my plugin in the <code>head</code> section of your
website:</p>

<pre><code>&lt;script src="jquery.min.js"&gt;&lt;/script&gt;
&lt;script src="jquery.cross-slide.min.js"&gt;&lt;/script&gt;
</code></pre></li>

<li><p>Put a block element somewhere in your page and give it an
<code>id</code>:</p>

<pre><code>&lt;div id="slideshow"&gt;&lt;/div&gt;
</code></pre></li>

<li><p>Make sure the element has a fixed size, even when emptied of its
contents, by setting its width and height in the CSS stylesheet:</p>

<pre><code>#slideshow {
  width: 600px;
  height: 200px;
}
</code></pre></li>

<li><p>Open a script tag, define a "document ready handler" and activate my
plugin on the <code>div</code> you created in step 2:</p>

<pre><code>&lt;script&gt;
  $(function() {
    $('#slideshow').crossSlide({
      sleep: 2,
      fade: 1
    }, [
      { src: 'picture1.jpg' },
      { src: 'picture2.jpg' },
      { src: 'picture3.jpg' },
      { src: 'picture4.jpg' }
    ])
  });
&lt;/script&gt;
</code></pre></li>
</ol>

<img src='error-console.png' align='right'>
<p>Things to keep in mind:</p>

<ul>
<li><p>Keep an eye on the Error console (in Firefox it's under the Tools menu)
as that's where my script will post any error messages you are supposed to
read, for example when the options you use don't make sense together.</p></li>
<li><p>Make sure the browser can find the images you reference in the
<code>src</code> attributes, relative to the path of the current page, because
if the browser cannot load them, my plugin has no way to know and will just
hangs there, without any error messages.</p></li>
<li><p>Don't put a comma after the last element in an array or object (this
means don't put a comma just before a closing brace or bracket, even if it's on
the previous line) because Internet Explorer won't like it and will refuse to
run the script, again without any error message.</p></li>
<li><p>Don't call <code>crossSlide()</code> on an empty set or on a set of more
than one element. This is not supported and will raise an exception—as you can
see clearly if you are keeping an eye on the Error Console.</p></li>
</ul>

<hr style="clear:both">

<p class=footer>
<a name=note1 href=#use1>1</a>: minified and gzipped, code only.<br></p>

<p class=footer>
Credits go to
<a href='http://flickr.com/photos/spacetrucker/94209642/'>spacetrucker</a>,
<a href='http://flickr.com/photos/hichako/1125341449/'>hichako</a>,
<a href='http://flickr.com/photos/jayniebell/1125216143/'>jayniebell</a>, and
<a href='http://flickr.com/photos/ruminatrix/1125292682/'>ruminatrix</a>
for the nice summer pictures.</p>

</div>

<script src='jquery-1.4.2.min.js'></script>
<script src='jquery.easing.min.js'></script>
<script src='http://github.com/tobia/Pause/raw/master/jquery.pause.min.js'></script>
<script src='http://github.com/tobia/CrossSlide/raw/master/jquery.cross-slide.min.js'></script>
<script src='script.js'></script>

<script type="text/javascript">
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-16555276-1']);
  _gaq.push(['_trackPageview']);
  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();
</script>

</body>
</html>
